﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using LowLevelGraphics;
using LowLevelGraphics.Types.Interval;

namespace ImageRecognition2.Forms
{
    /// <summary>
    /// Use this to create a Mask
    /// </summary>
    public partial class FormMask : Form
    {        
        protected Bitmap m_Source = null;
        protected List<ColorContainer> m_aColor = new List<ColorContainer>();
        protected UnsafeBitmap bitmapSource = null;

        protected static FormChild.PixelClickedEventHandler pixelClickedEventHandler = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="FormMask"/> class.
        /// </summary>
        public FormMask()
        {
            InitializeComponent();
            pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
            this.m_Source = (Bitmap)MainFormSingleton.ActivePictureBox.BackgroundImage;
            this.pictureBox1.BackgroundImage = (Bitmap)MainFormSingleton.ActivePictureBox.BackgroundImage.Clone();

            bitmapSource = new UnsafeBitmap((Image)this.m_Source.Clone());

            ActualizeColors(Definitions.White, toolStripButtonAddRemoveColor.Checked, m_Source, (Bitmap)this.pictureBox1.BackgroundImage);
            pictureBox1.Invalidate();

            pixelClickedEventHandler = new FormChild.PixelClickedEventHandler(FormChild_PixelClickedEvent);
            FormChild.PixelClickedEvent += pixelClickedEventHandler;
        }

        /// <summary>
        /// Handles the PixelClickedEvent event of the FormChild control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="ImageRecognition2.Forms.PixelClickedEventArgs"/> instance containing the event data.</param>
        void FormChild_PixelClickedEvent(object sender, PixelClickedEventArgs e)
        {
            m_aColor.Add(e.Color);
            ActualizeColors(e.Color, toolStripButtonAddRemoveColor.Checked, m_Source, (Bitmap)this.pictureBox1.BackgroundImage);
            this.pictureBox1.Invalidate();
        }

        /// <summary>
        /// Gets the picture box1.
        /// </summary>
        /// <value>The picture box1.</value>
        public PictureBox PictureBox1
        {
            get { return pictureBox1; }
        }

        /// <summary>
        /// Handles the Click event of the toolStripButtonChildList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButtonChildList_Click(object sender, EventArgs e)
        {
            FormChildList formChildList = new FormChildList();
            if (formChildList.ShowDialog() != DialogResult.OK) return;
            FormItem formItem = formChildList.FormItem;
            pictureBox1.Invalidate();
        }

        /// <summary>
        /// Handles the Click event of the toolStripButtonColorPicker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButtonColorPicker_Click(object sender, EventArgs e)
        {
            FormColorSelection formColorSelection = new FormColorSelection();
            if (formColorSelection.ShowDialog() != DialogResult.OK) return;

            Color formColorSelectionColor1 = formColorSelection.Color1;
            Color color = ColorFunctions.FromKnownColorComponent(formColorSelectionColor1);
            if (toolStripButtonAddRemoveColor.Checked)
            {
                m_aColor.Add(color);
            }
            else
            {
               int n1 =  m_aColor.IndexOf(color);
            }
            ActualizeColors(color, toolStripButtonAddRemoveColor.Checked, m_Source, (Bitmap)this.pictureBox1.BackgroundImage);
            pictureBox1.Invalidate();
        }

        /// <summary>
        /// Handles the Click event of the toolStripButtonPasteFromClipboard control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButtonPasteFromClipboard_Click(object sender, EventArgs e)
        {
            Bitmap bitmap = (Bitmap)Clipboard.GetData(DataFormats.Bitmap);
            if (bitmap == null) return;
            this.pictureBox1.BackgroundImage = bitmap;
            pictureBox1.Invalidate();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_aColor"></param>
        /// <param name="_bAdd"></param>
        /// <param name="_bitmapSource"></param>
        /// <param name="_bitmapMask"></param>
        public void ActualizeColors(Color _color, bool _bAdd, Bitmap _bitmapSource, Bitmap _bitmapMask)
        {
            int y = 0;
            int x = 0;

            UnsafeBitmap bitmapMask = _bitmapMask;

            Color color = Color.Transparent;
            
            if (m_aColor.Count == 0)
            {
                bitmapMask.Clear(Definitions.Black);
            }
            else
            {
                int nHeight = bitmapMask.Height;
                int nWidth = bitmapMask.Width;
                
                for (y = 0; y < nHeight; y++)
                {
                    for (x = 0; x < nWidth; x++)
                    {
                        color = m_Source.GetPixel(x, y);
                        if (color != Definitions.White)
                        {
                            if (color == _color) bitmapMask.SetPixel(x, y, Definitions.White);
                        }
                    }
                }
            }

            bitmapSource.Dispose();
            bitmapMask.Dispose();
        }

        /// <summary>
        /// 
        /// </summary>
        public class ColorContainer : IColorContainer
        {
            private ByteInterval m_ByteInterval = null;
            private Color m_Color = Color.Transparent;
            public ColorContainer(Color _color)
            {
                m_Color = _color;
            }

            /// <summary>
            /// Initializes a new instance of the <see cref="ColorContainer"/> class.
            /// </summary>
            /// <param name="_byteInterval">The _byte interval.</param>
            public ColorContainer(ByteInterval _byteInterval)
            {
                m_ByteInterval = _byteInterval;
            }

            /// <summary>
            /// Performs an implicit conversion from <see cref="System.Drawing.Color"/> to <see cref="ImageRecognition2.Forms.FormMask.ColorContainer"/>.
            /// </summary>
            /// <param name="_color">The _color.</param>
            /// <returns>The result of the conversion.</returns>
            public static implicit operator ColorContainer(Color _color)
            {
                return new ColorContainer(_color);
            }

            /// <summary>
            /// Performs an implicit conversion from <see cref="LowLevelGraphics.Types.Interval.ByteInterval"/> to <see cref="ImageRecognition2.Forms.FormMask.ColorContainer"/>.
            /// </summary>
            /// <param name="_byteInterval">The _byte interval.</param>
            /// <returns>The result of the conversion.</returns>
            public static implicit operator ColorContainer(ByteInterval _byteInterval)
            {
                return new ColorContainer(_byteInterval);
            }

            /// <summary>
            /// Determines whether [contains] [the specified _byte interval].
            /// </summary>
            /// <param name="_byteInterval">The _byte interval.</param>
            /// <returns>
            /// 	<c>true</c> if [contains] [the specified _byte interval]; otherwise, <c>false</c>.
            /// </returns>
            public bool Contains(ByteInterval _byteInterval)
            {
                return m_ByteInterval.Contains(_byteInterval);
            }

            /// <summary>
            /// Determines whether [contains] [the specified _color].
            /// </summary>
            /// <param name="_color">The _color.</param>
            /// <returns>
            /// 	<c>true</c> if [contains] [the specified _color]; otherwise, <c>false</c>.
            /// </returns>
            public bool Contains(Color _color)
            {
                return m_Color == _color;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public interface IColorContainer
        {

        }

        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Form.Closing"/> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.ComponentModel.CancelEventArgs"/> that contains the event data.</param>
        protected override void OnClosing(CancelEventArgs e)
        {
            FormChild.PixelClickedEvent -= pixelClickedEventHandler;
            base.OnClosing(e);
        }
    }
}
